<template>
    <div id="cesium-container">
    </div>
</template>
  
<script>
export default {
    name: 'ThreeDTilesClippingPlanes',
    components: {},
    mounted() {
        this.initViewer()
    },
    methods: {
        async initViewer() {
            Cesium.Ion.defaultAccessToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIzM2RjYjJlOC01ZTQwLTQwODYtOTEwMy02M2U4OGEzYjQyNGUiLCJpZCI6MjI5NjUsInNjb3BlcyI6WyJhc3IiLCJnYyJdLCJpYXQiOjE1ODI0NTYwMzF9.VG2_T9ry8EnBWAh4msJ3s6m2jW_5hgAZQvfEQDh-WQs"
            window.viewer = new window.Cesium.Viewer("cesium-container", {
                // terrainProvider: new window.Cesium.CesiumTerrainProvider({
                //     url: 'http://data.mars3d.cn/terrain',
                //     requestWaterMask: true,
                //     requestVertexNormals: true
                // }),
                imageryProvider: new window.Cesium.ArcGisMapServerImageryProvider({
                    url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
                }),
                sceneMode: window.Cesium.SceneMode.SCENE3D,
                vrButton: false,
                animation: false,
                baseLayerPicker: false,
                geocoder: false,
                timeline: false,
                fullscreenButton: false,
                homeButton: false,
                creditContainer: document.createElement('div'),
                infoBox: false,
                navigationHelpButton: false,
                sceneModePicker: false,
                scene3DOnly: true,
                skyBox: new window.Cesium.SkyBox({
                    sources: {
                        positiveX: require('@/assets/images/tycho2t3_80_px.jpg'),
                        negativeX: require('@/assets/images/tycho2t3_80_mx.jpg'),
                        positiveY: require('@/assets/images/tycho2t3_80_py.jpg'),
                        negativeY: require('@/assets/images/tycho2t3_80_my.jpg'),
                        positiveZ: require('@/assets/images/tycho2t3_80_pz.jpg'),
                        negativeZ: require('@/assets/images/tycho2t3_80_mz.jpg'),
                    }
                })
            });
            //开启地形深度检测
            window.viewer.scene.globe.depthTestAgainstTerrain = true;
            //加载3dtiles模型、定位
            let tileset = await new window.Cesium.Cesium3DTileset({
                url: window.Cesium.IonResource.fromAssetId(1240402),
            }).readyPromise
            window.viewer.scene.primitives.add(tileset);
            window.viewer.zoomTo(
                tileset,
                new window.Cesium.HeadingPitchRange(
                    0.0,
                    -0.5,
                    tileset.boundingSphere.radius * 2.0
                )
            );

            //裁剪平面移动量
            let targetY = 0.0;
            //当前选中的裁剪平面
            let selectedPlane;

            //鼠标左键按下操作句柄
            const downHandler = new window.Cesium.ScreenSpaceEventHandler(
                window.viewer.scene.canvas
            );
            downHandler.setInputAction(function (movement) {
                //拾取裁剪面实体
                const pickedObject = window.viewer.scene.pick(movement.position);
                if (
                    window.Cesium.defined(pickedObject) &&
                    window.Cesium.defined(pickedObject.id) &&
                    window.Cesium.defined(pickedObject.id.plane)
                ) {
                    //鼠标左键按下，并拾取到裁剪平面实体时，设置裁剪平面实体的颜色，边线，并将相机控制输入关闭
                    selectedPlane = pickedObject.id.plane;
                    selectedPlane.material = window.Cesium.Color.WHITE.withAlpha(0.05);
                    selectedPlane.outlineColor = window.Cesium.Color.WHITE;
                    window.viewer.scene.screenSpaceCameraController.enableInputs = false;
                }
            }, window.Cesium.ScreenSpaceEventType.LEFT_DOWN);

            //鼠标左键抬起操作句柄
            const upHandler = new window.Cesium.ScreenSpaceEventHandler(
                window.viewer.scene.canvas
            );
            upHandler.setInputAction(function () {
                if (window.Cesium.defined(selectedPlane)) {
                    //鼠标左键抬起时，设置裁剪平面实体的颜色、边线、销毁当前选中的裁剪平面实体
                    selectedPlane.material = window.Cesium.Color.WHITE.withAlpha(0.1);
                    selectedPlane.outlineColor = window.Cesium.Color.WHITE;
                    selectedPlane = undefined;
                }
                //恢复相机控制输入
                window.viewer.scene.screenSpaceCameraController.enableInputs = true;
            }, window.Cesium.ScreenSpaceEventType.LEFT_UP);

            //鼠标移动操作句柄
            const moveHandler = new window.Cesium.ScreenSpaceEventHandler(
                window.viewer.scene.canvas
            );
            moveHandler.setInputAction(function (movement) {
                if (window.Cesium.defined(selectedPlane)) {
                    //鼠标移动后，计算移动量，并将移动量叠加到targetY
                    const deltaY = movement.startPosition.y - movement.endPosition.y;
                    targetY += deltaY;
                }
            }, window.Cesium.ScreenSpaceEventType.MOUSE_MOVE);

            //为模型数据集设置裁剪平面
            tileset.clippingPlanes = new window.Cesium.ClippingPlaneCollection({
                planes: [
                    //设置一个垂直于Z轴的裁剪平面
                    new window.Cesium.ClippingPlane(new window.Cesium.Cartesian3(0.0, 0.0, -1.0), 0)
                ],
                edgeWidth: 3
            });

            const boundingSphere = tileset.boundingSphere;
            const radius = boundingSphere.radius;

            //遍历数据集的裁剪平面，构建裁剪平面实体
            for (let i = 0; i < tileset.clippingPlanes.length; i++) {
                let plane = tileset.clippingPlanes.get(i)
                window.viewer.entities.add({
                    position: boundingSphere.center,
                    plane: {
                        //平面的范围(边界)
                        dimensions: new window.Cesium.Cartesian2(
                            radius * 2.5,
                            radius * 2.5
                        ),
                        material: window.Cesium.Color.WHITE.withAlpha(0.1),
                        plane: new window.Cesium.CallbackProperty(
                            () => {
                                plane.distance = targetY;
                                return plane;
                            },
                            false
                        ),
                        outline: true,
                        outlineColor: window.Cesium.Color.WHITE,
                    },
                });
            }
        }
    }
}
</script>
  
<style>
#cesium-container {
    width: 100%;
    height: 100%;
}
</style>
  